﻿using Microsoft.AspNetCore.Mvc;
using System;
using ZhCun.DBModel;
using ZhCun.Utils;
using ZhCun.Utils.Helpers;
using ZhCun.WebUtils;
using ZhCun.WebUtils.Authorizes;
using ZhCun.WebUtils.Configs;
using ZhCun.WebUtils.DB;

namespace ZhCun.WebUtils
{
    [ApiExplorerSettings(GroupName = "RightsManage")]
    public class BaseApiUserController<TUserBLL> : BaseApiController<TUserBLL>
        where TUserBLL : UserBaseBLL, new()
    {
        const string ENCRYPT_BODY_KEY = "{FB41C113-3074-4A88-B998-33E66DEAAB9E}";

        const string IMG_CODE_KEY = "{ACC9D599-6D09-4B4A-B837-5A6B5E541A1A}";
        /// <summary>
        /// 登陆验证
        /// </summary>
        /// <param name="arg">登陆参数（忽略）</param>
        /// <param name="loginType">登陆类型 0: page, 1: webapi</param>
        /// <returns></returns>
        [NonAction]
        protected ApiResult Login(UserLoginArg arg, int loginType)
        {
            var ret = LoginCustom<UserLoginRet>(arg, loginType);
            return ret;
        }
        /// <summary>
        /// 自定义结果的登陆验证
        /// </summary>
        /// <typeparam name="TRet"></typeparam>
        /// <param name="arg"></param>
        /// <param name="loginType"></param>
        /// <returns></returns>
        [NonAction]
        protected ApiResult<TRet> LoginCustom<TRet>(UserLoginArg arg, int loginType)
            where TRet : UserLoginRet, new()
        {
            if (arg.LoginName.IsEmpty())
            {
                return this.RetErr<TRet>("用户名不能为空");
            }

            if (arg.LoginName.IsEmpty())
            {
                return this.RetErr<TRet>("密码不能为空");
            }
            if (loginType == 0)
            {
                var imgCode = HttpContext.GetSession(IMG_CODE_KEY, true);
                if (!arg.VerifyCode.StringEquals(imgCode))
                {
                    return this.RetErr<TRet>("验证码错误");
                }
            }
            var r = BLLObj.Login(arg, loginType);
            if (!r)
            {
                return this.RetErr<TRet>(r.msg);
            }

            LoginUser user = r.data;

            int expiresMin = loginType == 1 ? CommonConfig.THIS.TokenTimeOutApi : CommonConfig.THIS.TokenTimeOutPage;
            user.Expires = TimeSpan.FromMinutes(expiresMin);
            string token = LoginState.Set(user);
            if (loginType == 1)
            {
                return BLLObj.RetOK(new TRet
                {
                    Token = token,
                    UserName = user.UserName,
                    ExpiresTime = user.ExpiresTime
                });
            }
            else
            {
                HttpContext.SetCookieToken(token, user.ExpiresTime);
                return BLLObj.RetOK<TRet>(null, "登陆成功");
            }
        }

        /// <summary>
        /// 获取登录验证码
        /// </summary>
        [HttpGet]
        [UserAuthorize(false)]
        [BodyEncryptFilter(false)]
        public IActionResult GetLoginVerifyCode()
        {
            var img = ImageHelper.GetVerifyCodeToBytes(110, 40, 5, out string code);
            HttpContext.SetSession(IMG_CODE_KEY, code);
            return File(img, @"image/jpeg");
        }
        /// <summary>
        /// token登录，重新登录时通过token，失败时请使用用户名登录，ClientSN不一致验证不通过
        /// </summary>        
        [HttpPost]
        public ApiResult LoginToken()
        {
            UserLoginRet ret = new UserLoginRet();
            ret.Token = LoginState.CreateToken(CurrUser);
            ret.UserName = CurrUser.UserName;
            ret.ExpiresTime = CurrUser.ExpiresTime;
            return BLLObj.RetOK(ret);
        }
        /// <summary>
        /// 保存用户信息
        /// </summary>
        [HttpPost]
        public ApiResult InfoSave(Sys_User m)
        {
            var r = BLLObj.SaveInfo(m);
            return r;
        }
        /// <summary>
        /// 修改密码保存
        /// </summary>
        [HttpPost]
        public ApiResult ChangePwd(User_ChangePwd arg)
        {
            return BLLObj.ChangePwd(arg);
        }
        /// <summary>
        /// 用户登录退出
        /// </summary>
        [HttpPost]
        public ApiResult LoginOut()
        {
            var ret= BLLObj.LoginOut();
            var token = HttpContext.GetToken();
            LoginState.Remove(token);
            HttpContext.DelCookieToken();
            return ret;
        }

        /// <summary>
        /// 获取加密参数
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [UserAuthorize(false)]
        [BodyEncryptFilter(false)]
        public ApiResult GetEncryptArg()
        {
            if (!CommonConfig.THIS.RsaBodyEnable)
            {
                return this.RetErr("body not encrypt");
            }
            var argObj = MemoryCacheHelper.Get(ENCRYPT_BODY_KEY);
            if (argObj == null)
            {
                string rsaKey = System.IO.File.ReadAllText($"{AppContext.BaseDirectory}{CommonConfig.THIS.RsaBodyPubKey}");
                argObj = new
                {
                    EncryptKey = rsaKey,
                    EncryptName = CommonConfig.THIS.BodyEncryptKeyName,
                    AddTime = DateTime.Now,
                    Remark = "张存测试"
                };
                MemoryCacheHelper.Set(ENCRYPT_BODY_KEY, argObj);
            }
            return this.RetOK(argObj);
        }
    }

    public class BaseApiUserController : BaseApiUserController<UserBaseBLL>
    {

    }
}